﻿using System;
using System.Collections.Generic;
using System.ComponentModel.Design;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace genshin_gacha
{
    internal class WeaponPrService
    {
        //private object result;

        public WeaponPrService() { 
        }
        public double BasePR(int i)
        {
            return  i==0?0: Math.Min(i < 63 ? (double)0.007 : (double)(i<72?BasePR(i - 1) + (double)0.07: BasePR(i - 1) + (double)0.035),1);
        }

        public double NotGetPR(int i)
        {
            return i == 0 ? (double)1 : NotGetPR(i - 1) * (1 - BasePR(i));
        }
        /// <summary>
        /// 保底抽数
        /// </summary>
        public int Limit { get; private set; } = 80;
        /// <summary>
        /// 打算抽几个UP
        /// </summary>
        public int GachaCount { get; set; } = 1;
        /// <summary>
        /// 最大定规数
        /// </summary>
        public int MaxFailCount { get; set; } = 2;
        /// <summary>
        /// UP不外概率
        /// </summary>
        public double WinPR { get; set; } = (double)0.375;


        public double GetPR(int i)
        {
            return (i==0||i>Limit)?0:NotGetPR(i - 1) * BasePR(i);
        }
        private double GetWinPR(int failCount)
        {
            return Math.Pow(1 - WinPR, failCount)*(MaxFailCount==failCount?1:WinPR);
        }
        public double GetUpPR(int i)
        {
            double sum = 0d;
            for (var k = 0; k < MaxFailCount + 1; k++)
            {
                sum += i < k ? 0 : GetWinPR(k) * GetSubPRSum(i, k);
            }

            return sum;
            double a = 0, b = 0, c = 0;
            //Console.WriteLine("------------------");
            if (i <= Limit)
            {

                //a = GetWinPR(0) * GetPR(i);

                //b = GetWinPR(1) * GetSubPRSum(i, 1);  //获得UP五星概率
                ////j:前两次抽中的总数,k:第一抽中的数量,j-k:第二次抽中的数量

                //c = i < 2 ? 0 : GetWinPR(2) * GetSubPRSum(i, 2);
                


            }
            else if (i <= Limit * 2)
            {

                b = GetWinPR(1) * GetSubPRSum(i, 1);

                //c = GetWinPR(2) * Enumerable.Range(2, Math.Min(i - 2, Limit * 2))
                //.Select(j => Enumerable.Range(1, Math.Min(j - 1, Limit)).Select(k => GetPR(k) * GetPR(j - k) ).Sum() * GetPR(i - j))
                //.Sum();
                c = GetWinPR(2) * GetSubPRSum(i, 2);
            }
            else
            {

                c = GetWinPR(2) * GetSubPRSum(i, 2);
                //Enumerable.Range(2, Math.Min(i - 2, Limit * 2))
                //.Select(j => GetSubPR(j,1).Sum() * GetPR(i - j))
                //.Sum();

            }
            return a + b + c;


        }

        private double GetSubPRSum(int i,int f)
        {
            return f==0? GetPR(i): Enumerable.Range(f, Math.Min(i - f, Limit*f)).Select(k => (f==1?GetPR(k): GetSubPRSum(k,f-1)) * GetPR(i - k)).Sum();
        }
    }
}
